#include "list.h"

ListNode* CreateNode(int val) {
  ListNode* node = new ListNode();
  node->value = val;
  node->next = nullptr;
  return node;
}

DoubleListNode* CreateDoubleListNode(int val) {
  DoubleListNode* node = new DoubleListNode();
  node->value = val;
  node->pre = nullptr;
  node->next = nullptr;
  return node;
}

ListNode* ConnectNode(ListNode* pre, ListNode* next) {
  pre->next = next;
  return pre;
}

DoubleListNode* ConnectDoubleListNode(DoubleListNode* pre, DoubleListNode* next) {
  pre->next = next;
  next->pre = pre;
  return pre;
}

ListNode* CreateList(std::vector<int> nodes_values) {
    if (nodes_values.empty()) {
        return nullptr;
    }
    ListNode* root = new ListNode();
    root->value = nodes_values.front();
    root->next = nullptr;

    ListNode* root_tmp = root;
    for (size_t i = 1; i < nodes_values.size(); i++) {
        ListNode* new_node = new ListNode();
        new_node->value = nodes_values[i];
        new_node->next = nullptr;

        root_tmp->next = new_node;
        root_tmp = root_tmp->next;
    }
    return root;
}

DoubleListNode* CreateDoubleList(std::vector<int> nodes_values) {
    if (nodes_values.empty()) {
        return nullptr;
    }
    DoubleListNode* root = new DoubleListNode();
    root->value = nodes_values.front();
    root->pre = nullptr;
    root->next = nullptr;

    DoubleListNode* root_tmp = root;
    for (size_t i = 1; i < nodes_values.size(); i++) {
        DoubleListNode* new_node = new DoubleListNode();
        new_node->value = nodes_values[i];
        new_node->pre = root_tmp;
        new_node->next = nullptr;

        root_tmp->next = new_node;
        root_tmp = root_tmp->next;
    }
    return root;
}

void PrintList(ListNode* root) {
    auto node = root;
    while (node) {
        std::cout << node->value << " ";
        node = node->next;
    }
    std::cout << std::endl;
}

void PrintDoubleList(DoubleListNode* root) {
  auto node = root;
  auto tail_node = root;
  std::cout << "------------------------" << std::endl;
  std::cout << "Print double list: " << std::endl;
  while (node) {
    if (!node->next) {
      tail_node = node;
    }
    std::cout << node->value << " ";
    node = node->next;
  }
  std::cout << std::endl;
  node = tail_node;
  while (node) {
    std::cout << node->value << " ";
    node = node->pre;
  }
  std::cout << std::endl;
  std::cout << "------------------------" << std::endl;
}

void DeleteList(ListNode* root) {
    ListNode* node = root;
    while (node) {
        root = node->next;
        delete node;
        node = root;
    }
}

void DeleteDoubleList(DoubleListNode* root) {
    DoubleListNode* node = root;
    while (node) {
        root = node->next;
        delete node;
        node = root;
    }
}
